/**
 * ES6写法的JSBridge
 *
 * @export
 * @class JSBridge
 */

const nativeRouteConfig = require('../router/native')

export default class JSBridge {
  constructor () {
    this.name = 'JSBridge'
    this.reset = true
    this.instance = null
    this.userAgent = 'h5'
  }

  static getInstance () {
    if (!this.instance) {
      this.instance = new JSBridge()
    }
    return this.instance
  }

  /**
   * 判断设备类型
   *
   * @returns
   * @memberof JSBridge
   */
  device () {
    var u = navigator.userAgent
    var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1
    // eslint-disable-next-line
    var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)

    if (process.env.NODE_ENV === 'production') {
      if (isAndroid) {
        this.userAgent = 'android'
      } else if (isiOS) {
        this.userAgent = 'ios'
      } else {
        this.userAgent = 'h5'
      }
    }

    return isAndroid
  }

  /**
   * 解析跳转参数
   *
   * @returns
   * @memberof JSBridge
   */
  resolveLink (link) {
    console.log('orign link:', link)
    if (typeof link === 'string' && link.constructor === String) {
      if (process.env.NODE_ENV === 'development') {
        return {
          name: link
        }
      }
      return {
        class: nativeRouteConfig.default,
        url: link
      }
    }
    if (!(typeof link === 'object' && link.constructor === Object)) {
      return false
    }
    let routeConfig = nativeRouteConfig.routes.find((element) => (element.type === link.type))
    if (typeof routeConfig !== 'object') {
      return false
    }
    // 删除link中的类型
    delete link.type

    let isAndroid = this.device()
    let userAgent = this.userAgent
    let params = {}
    if (routeConfig.alias && typeof routeConfig.alias[userAgent] !== 'undefined' && Object.keys(routeConfig.alias[userAgent]).length !== 0) {
      let agentAlias = routeConfig.alias[userAgent]
      Object.getOwnPropertyNames(link).forEach(function (index) {
        let newIndex = agentAlias[index] ? agentAlias[index] : index
        params[newIndex] = link[index]
      })
    } else {
      params = link
    }
    let type = {}
    if (process.env.NODE_ENV === 'development') {
      type['name'] = routeConfig.route
    } else {
      if (isAndroid) {
        type['classname'] = routeConfig.className + 'Activity'
      } else {
        type['class'] = routeConfig.className + 'ViewController'
      }
    }
    return Object.assign(type, {
      property: params
    })
  }

  /**
   * 解析跳转参数
   *
   * @returns
   * @memberof JSBridge
   */
  checkNativeLink (name) {
    if (typeof name === 'string' && name.constructor === String) {
      return nativeRouteConfig.nativeMap.includes(name)
    }
    return false
  }

  /**
   * JSBridge初始化
   *
   * @param {*} callback
   * @returns
   * @memberof JSBridge
   */
  _init (callback) {
    const isAn = this.device()
    if (isAn) {
      if (window.WebViewJavascriptBridge) {
        // eslint-disable-next-line
        callback(WebViewJavascriptBridge)
      } else {
        document.addEventListener(
          'WebViewJavascriptBridgeReady',
          function () {
            // eslint-disable-next-line
            callback(WebViewJavascriptBridge)
          },
          false
        )
      }
      return
    }

    if (window.WebViewJavascriptBridge) {
      // eslint-disable-next-line
      return callback(WebViewJavascriptBridge)
    }
    if (window.WVJBCallbacks) {
      return window.WVJBCallbacks.push(callback)
    }
    window.WVJBCallbacks = [callback]
    var WVJBIframe = document.createElement('iframe')
    WVJBIframe.style.display = 'none'
    WVJBIframe.src = 'wvjbscheme://__bridge_loaded__'
    document.documentElement.appendChild(WVJBIframe)
    setTimeout(function () {
      document.documentElement.removeChild(WVJBIframe)
    }, 0)
  }

  /**
   * 安卓设备的初始化
   * @param {*} bridge
   */
  __init__ (bridge) {
    const isAn = this.device()
    if (this.reset && isAn) {
      this.reset = false
      bridge.init(function (message, responseCallback) {
        console.log('JS got a message', message)
        var data = {
          'Javascript Responds': '测试中文!'
        }
        console.log('JS responding with', data)
        responseCallback(data)
      })
    }
  }

  /**
   * 获取用户信息
   *
   * @param {*} data
   * @param {*} callback
   * @memberof JSBridge
   */
  getUserInfo (data, callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.callHandler('getUserInfo', data, function (response) {
        console.log(response)
        callback(formatParseJson(response))
      })
    }.bind(this))
  }

  jsEcho (callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.registerHandler('JS Echo', function (data, responseCallback) {
        console.log('JS Echo called with:', data)
        responseCallback(callback(formatParseJson(data)))
      })
    }.bind(this))
  }

  /**
   * 原生webview万能跳转
   * @param {*} link
   * @param {*} callback
   */
  pushWeb (link, callback) {
    if (process.env.NODE_ENV === 'development') {
      setTimeout(function () {
        callback(link)
      }, process.env.LOADING_TIME)
    } else {
      this._init(function (bridge) {
        this.__init__(bridge)
        bridge.callHandler('nativePush', link, function (response) {
          callback(response)
        })
      }.bind(this))
    }
  }

  /**
   * 调起原生webview通用
   * @param {*} data
   * @param {*} callback
   */
  callNativeHandler (data, callback) {
    if (process.env.NODE_ENV === 'development') {
      setTimeout(function () {
        let response = {
          status: true,
          message: 'Success'
        }
        callback(response)
      }, process.env.LOADING_TIME)
    } else {
      this._init(function (bridge) {
        /**
         * Json format:
         * {
         *  scheme: 'Magic',
         *  route: 'http://vue.domain.com/#/goods/1',
         *  data: {
         *    id: 1,
         *    type: 'video',
         *  }
         * }
         */
        this.__init__(bridge)
        bridge.callHandler('callNativeHandler', data, function (response) {
          callback(response)
        })
      }.bind(this))
    }
  }

  /**
   * 打开原生功能页面
   * @param {*} callback
   */
  pushNative (data, callback) {
    if (process.env.NODE_ENV === 'development') {
      setTimeout(function () {
        let response = {
          status: true
        }
        callback(response)
      }, process.env.LOADING_TIME)
    } else {
      this._init(function (bridge) {
        this.__init__(bridge)
        bridge.callHandler('openNativePage', data, function (response) {
          callback(response)
        })
      }.bind(this))
    }
  }

  /**
   * 原生调起H5购物车的编辑状态
   * @param {*} callback
   */
  shopCartEdit (callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.registerHandler('shopCartEdit', (data) => {
        console.log('购物车编辑回调: ', data)
        callback(formatParseJson(data))
      })
    }.bind(this))
  }

  /**
   * 原生点赞后回调H5
   * @param {*} callback
   */
  commentLiked (callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.registerHandler('commentLiked', (data) => {
        console.log('点赞回调: ', data)
        callback(formatParseJson(data))
      })
    }.bind(this))
  }

  /**
   * 导航栏上新增收货地址动作
   * @param {*} callback
   */
  addAddress (callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.registerHandler('addAddress', (data, responseCallback) => {
        console.log('新增收货地址回调: ', data)
        responseCallback(callback(data))
      })
    }.bind(this))
  }

  /**
   * 导航栏上删除收货地址动作
   * @param {*} callback
   */
  deleteAddress (callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.registerHandler('deleteAddress', (data, responseCallback) => {
        console.log('删除收货地址回调: ', data)
        responseCallback(callback(data))
      })
    }.bind(this))
  }

  /**
   * 从原生获取登录令牌
   * @param {*} callback
   */
  getAccessToken (callback) {
    if (process.env.NODE_ENV === 'development') {
      setTimeout(function () {
        callback(process.env.ACCESS_TOKEN)
      }, process.env.LOADING_TIME)
    } else {
      this._init(function (bridge) {
        this.__init__(bridge)
        bridge.callHandler('getAccessToken', {}, function (response) {
          console.log(response)
          callback(formatParseJson(response).accessToken)
          // callback(response)
        })
      }.bind(this))
    }
  }

  /**
   * 显示支付弹框 选择支付方式
   * @param {*} callback
   */
  showPaymentControl (data, callback) {
    if (process.env.NODE_ENV === 'development') {
      setTimeout(function () {
        let response = {
          status: false
        }
        callback(response)
      }, process.env.LOADING_TIME)
    } else {
      this._init(function (bridge) {
        this.__init__(bridge)
        bridge.callHandler('showPaymentControl', data, (response) => {
          callback(response)
        })
      }.bind(this))
    }
  }

  /**
   *  关闭支付弹窗回调
   * @param {*} callback
   */
  closePaymentControl (callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.registerHandler('closePaymentControl', () => {
        console.log('关闭支付弹窗回调')
        callback()
      })
    }.bind(this))
  }

  /**
   * iOS监听加载成功
   * @param {*} callback
   */
  finishLoaded (callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.callHandler('finishLoaded', {}, function (response) {
        callback()
      })
    }.bind(this))
  }

  /**
   * 配置右上角按钮
   * @param {*} data
   * @param {*} callback
   */
  configRightBar (data, callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.callHandler('configRightBar', data, function (response) {
        callback()
      })
    }.bind(this))
  }

  /**
   * 给原生发送分享数据
   * @param {*} data
   * @param {*} callback
   */
  share (data, callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.callHandler('share', data, function (res) {
        callback()
      })
    }.bind(this))
  }

  /**
   * 重现页面监听
   * @param {*} callback
   */
  webviewAppear (callback) {
    console.log('webviewAppear: im back')
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.registerHandler('webviewAppear', () => {
        console.log('页面重现监听到了')
        callback()
      })
    }.bind(this))
  }

  /**
   * 完成支付
   * @param {*} data
   * @param {*} callback
   */
  finishPay (data, callback) {
    console.log('finishpay start')
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.registerHandler('finishPay', function (data, responseCallback) {
        console.log('支付完成回调')
        callback()
      })
    }.bind(this))
  }

  /**
   * 跳转到登录界面
   * @param {*} data
   * @param {*} callback
   */
  goToLoginPage (data, callback) {
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.callHandler('goToLoginPage', data, function (res) {
        callback()
      })
    }.bind(this))
  }

  /**
   * 获取状态栏高度
   * @param {*} callback
   */
  getClientLayout (callback) {
    if (process.env.NODE_ENV === 'development') {
      let h = {
        statusBarHeight: 3.5
      }
      setTimeout(function () {
        callback(h)
      }, process.env.LOADING_TIME)
    } else {
      this._init(function (bridge) {
        this.__init__(bridge)
        bridge.callHandler('getClientLayout', {}, function (response) {
          callback(response)
        })
      }.bind(this))
    }
  }

  /**
   * 调用原生上传功能
   * @param {*} data
   * @param {*} callback
   */
  uploadAttach (data, callback) {
    console.log(data)
    if (process.env.NODE_ENV === 'development') {
      let attach = {
        'id': 9,
        'path': '/attachments/default/201811/03/mhK0vDNyqQ44N0baDpG0kjAVcfLH0c0h.png',
        'url': 'http://lumihui.img.emhome.cn/attachments/default/201811/03/mhK0vDNyqQ44N0baDpG0kjAVcfLH0c0h.png',
        'size': 173260,
        'channel': 'OSS',
        'isimage': 1,
        'width': 439,
        'height': 438
      }
      setTimeout(function () {
        callback(attach)
      }, process.env.LOADING_TIME)
    } else {
      this._init(function (bridge) {
        this.__init__(bridge)
        bridge.callHandler('uploadAttach', data, function (response) {
          callback(response)
        })
      }.bind(this))
    }
  }

  /**
   * 上传回调监听
   * @param {*} callback
   */
  uploadComplete (callback) {
    console.log('Upload status listening...')
    if (process.env.NODE_ENV === 'development') {
      let attach = {
        'id': 9,
        'path': '/attachments/default/201811/03/mhK0vDNyqQ44N0baDpG0kjAVcfLH0c0h.png',
        'url': 'http://lumihui.img.emhome.cn/attachments/default/201811/03/mhK0vDNyqQ44N0baDpG0kjAVcfLH0c0h.png',
        'size': 173260,
        'channel': 'OSS',
        'isimage': 1,
        'width': 439,
        'height': 438
      }
      setTimeout(function () {
        callback(attach)
      }, process.env.LOADING_TIME)
    } else {
      this._init(function (bridge) {
        this.__init__(bridge)
        bridge.registerHandler('uploadComplete', (data) => {
          console.log('上传完成，接收到了回调信息: ', data)
          callback(formatParseJson(data))
        })
      }.bind(this))
    }
  }

  /**
   * 关闭当前webview页面
   * @param {*} callback
   */
  closeWebViewPage (data = {}, callback) {
    console.log('close on click')
    this._init(function (bridge) {
      this.__init__(bridge)
      bridge.callHandler('closeWebViewPage', data, function (res) {
        callback(res)
      })
    }.bind(this))
  }

  /**
   * 商品详情页的客服消息跳转
   * @param {*} data
   * @param {*} callback
   */
  openServiceMessage (data, callback) {
    console.log('客服消息测试')
    this._init(function (bridge) {
      this.__init__(bridge)
      console.log(bridge)
      bridge.callHandler('openServiceMessage', data, function (res) {
        console.log('打开客服消息')
        callback()
      })
    }.bind(this))
  }
}

/**
 * 格式化解析内容为JSON对象
 * @param {*} data
 */
export const formatParseJson = (data) => {
  if (typeof data === 'object' && data.constructor === Object) {
    return data
  } else {
    return JSON.parse(data)
  }
}
